package mrusanov.staff

import mrusanov.team.Club
import java.util.Date
import mrusanov.team.ClubStaff

class StaffMarket(yearStart: Date, private var _notSignedStaff: Set[ClubEmployee]) {
	private val DEFAULT_YEARS_FOR_FIRST_CONTRACT = 1

	private var proposals: Map[ClubEmployee, Club] = Map()
	private var proposedClubs: Set[Club] = Set()

	def notSignedStaff = _notSignedStaff

	def addClubProposal(club: Club, clubProposal: List[ClubEmployee]) {
		require(validateProposal(club, clubProposal))
		clubProposal foreach (addProposal(_, club))
	}

	def validateProposal(club: Club, clubProposal: List[ClubEmployee]): Boolean = {
		val allCanBeAdded = clubProposal.forall(_.canBeAddedToClubStaff(club))
		if (!allCanBeAdded) {
			return false
		}

		// require there are no same types of employee, except for coaches
		val propositionsByClass = clubProposal.groupBy(_.getClass())
		val typesOfEmployeeValid = propositionsByClass forall (kv => {
			val typeOfEmp = kv._1
			val sizeOfEmp = kv._2.size

			if (typeOfEmp == classOf[Coach]) {
				sizeOfEmp <= ClubStaff.MAX_COACHES - club.clubStaff.coachList.size
			} else {
				sizeOfEmp == 1
			}
		})

		typesOfEmployeeValid
	}

	private def addProposal(employee: ClubEmployee, club: Club) {
		if (!employee.isClubInfrastructureGoodEnough(club)) {
			return
		}

		val currentProposal = proposals.get(employee)
		currentProposal match {
			case Some(anotherClub) => {
				if (anotherClub.eloRating < club.eloRating) {
					proposals -= (employee)
					proposals += (employee -> club)
				}
			}

			case None => proposals += (employee -> club)
		}
	}

	def endSelectionRound() {
		proposals.foreach(kv => {
			val employee = kv._1
			val club = kv._2
			employee.contract = Some(Contract.createContractForClubEmployee(yearStart, DEFAULT_YEARS_FOR_FIRST_CONTRACT))
			employee.addToClubStaff(club)
		})

		proposals = Map()
	}
}